#include "Analyzer.h"
#include "globvars.h"

CAnalyzer::CAnalyzer(void)
{

}
CAnalyzer::CAnalyzer(std::string path, std::map<std::string, std::string> ini):
m_inifile(ini), m_path(path)
{
 	Main();
}

CAnalyzer::~CAnalyzer(void)
{
}
bool CAnalyzer::GetParam(string bl, void *val, unsigned short type)
{
  //cout<<"Get block: "<<bl.c_str()<<endl;
  //cout<<"Here: "<<m_inifile[bl.c_str()].c_str()<<endl;
	if(m_inifile.count(bl))
	{
	  if(type==0)//STRING
	    {
	      strcpy((char*)val,m_inifile[bl.c_str()].c_str());		
	    }
	 else
	   if(type==1)//INT
	     {
	       int ival=atoi(m_inifile[bl.c_str()].c_str());
	       memcpy(val, &ival, sizeof(int));
	     }else//DOUBLE
	       {
		 double dval=atof(m_inifile[bl.c_str()].c_str());
		 memcpy(val, &dval, sizeof(double));
	       }
	}else
	  {
	    cout<<"# Cannot find block in INI: "<<bl<<endl;
	    return false;
	  }
	return true;	
}
	
void CAnalyzer::Main(void)
{
	scoped_timer timethis("#All Analysis ");
	///////////////////////////////////////////////
	char strParam[256]="";
	int NUM_THREADS;
	int ANALYSIS_PROFILE=1, ANALYSIS_DUMP_OAF=0;
	bool TEST_FLAG=true;
	if(GetParam("ANALYSIS.PARAMFILE",(void*)strParam))
	  {
	    string paramf=m_path+"ANALYSIS/OAF/"+strParam;	    
	    read_parameterfile(paramf.c_str());
	  }else
	    {
	      string cc;
	      std::cout<<
		"# SETUP parapeters by default using internal logic"<<std::endl;
	      //MakeParamFile
	      GetParam("RUN.CODE",(void*)strParam);
	      if(strcmp(strParam,"GADGET-2")==0)
		{
		  cc=m_path+"RUNG2/SNAPS/";
		}else
		  cc=m_path+"RUNG2/SNAPS/";
	      strcpy(SnapDir, cc.c_str());
	      
	      GetParam("RUN.SNAP_MASK",(void*)SnapMask);
	      //////////////////////
	      //  ANALYSIS
	     
	      cc=m_path+"ANALYSIS/OAF/";
	      strcpy(OutputDir, cc.c_str());
	      
	      cc="";
	      GetParam("ANALYSIS.OAF_ID_FILE",(void*)strParam);
	      cout<<strParam<< endl;
	      strcpy(OAF_ID_FILE, strParam);
	      if(!GetParam("ANALYSIS.OAF_FROM_IDFILE",(void*)&OAF_FROM_IDFILE, 1))
		OAF_FROM_IDFILE=0;
		
	      GetParam("ANALYSIS.FOAF",(void*)strParam);
	      cout<<strParam<< endl;
	      
	      strcpy(OutputFile, strParam);
	      cc=cc+OutputFile;
	      
	      
	      strcpy(OutputFile, cc.c_str());
	      

	      if(!GetParam("ANALYSIS.PROFILE",(void*)&ANALYSIS_PROFILE, 1))
		ANALYSIS_PROFILE=1;
	      if(ANALYSIS_PROFILE ==1)
		{
		  // Init here the profiler parameters:
		  if(!GetParam("ANALYSIS.profRMAX",(void*)&profRMAX, 2))
		    profRMAX=10.0f;
		  
		  if(!GetParam("ANALYSIS.xStep", (void*)&xStep, 2))
		    xStep=0.02;
		  if(!GetParam("ANALYSIS.fm", (void*)&fm, 1))
		    fm=2;
		  if(!GetParam("ANALYSIS.NCOEF", (void*)&NCOEF, 1))
		    NCOEF=512;		   

		}
	      
	      if(!GetParam("ANALYSIS.SNAP_STEP",(void*)&SNAP_STEP, 1))
		SNAP_STEP=1;
	      if(!GetParam("ANALYSIS.SNAP_START",(void*)&SNAP_START, 1))
		SNAP_START=0;
	      if(!GetParam("ANALYSIS.SNAP_END",(void*)&SNAP_END, 1))
		SNAP_END=2000;
	      SNAP_END+=1;//Include last end
	       if(!GetParam("ANALYSIS.RMIN",(void*)&RMIN, 2))
		RMIN=0;
	       
	       if(!GetParam("ANALYSIS.RMAX",(void*)&RMAX, 2))
		RMAX=100;	       	    	      
	       
	       if(!GetParam("ANALYSIS.TYPE",(void*)&TYPE, 1))
		 TYPE=4;
	       ////////////////// AFOF SETUP ////////////
	       if(!GetParam("AFOF.AFOF_MASK",(void*)&AFOF_MASK))
		 strcpy(AFOF_MASK,"ST_e0.05_%04d");

	       cc=m_path+"ANALYSIS/AFOF/"+AFOF_MASK;
	       strcpy(AFOF_MASK,cc.c_str());
	       ////////////////// AFOF SETUP ////////////

	       sprintf(COM_FILE,"%s/%s%d%s",m_path.c_str(),
		       "ANALYSIS/COM_",4,".txt");// Here we are using TYPE=4 only COM

	       if(!GetParam("ANALYSIS.NUM_THREADS",(void*)&NUM_THREADS, 1))
		 NUM_THREADS=1;

	       ANALYSIS_DUMP_OAF= !ANALYSIS_PROFILE;

	    }
		
	CAnalysis *Analysis=new CAnalysis();/* Note this uses global variables they need to be initilized*/
	Analysis->SetNumberOfThreads(NUM_THREADS);
	///////////////////////////////////////////////
	// Lets Fill Job Queue ////////////////////////
	TSpecificFunctor<CAnalysis> 
	  tLoadSnaps(Analysis, &CAnalysis::do_parallel_load_on_SNAPS);

	if(ANALYSIS_DUMP_OAF)
	  m_jobsQueue.insert(make_pair("CAnalysis::do_parallel_load_on_SNAPS", &tLoadSnaps));
	////////////////////////////////////////////////
	if(TEST_FLAG)
	  {
	    for(int i=0;i<5;i++)cout<<"#WARNING\t";
	    cout<<"\n#To do real profiling you should uncomment this lines!!!!\n"<<endl;
	    cout << "# in file:"<<__FILE__<<" line:"<< __LINE__<<endl;
	    cout<<"# WARNING END"<<endl;
	    for(int i=0;i<25;i++)cout<<"#";
	    cout<<endl;
	  }
	TSpecificFunctor<CAnalysis> 
	  tProfSNAP(Analysis, &CAnalysis::do_parallel_Profiler_on_SNAP);
	if(ANALYSIS_PROFILE)	
	  m_jobsQueue.insert(make_pair("CAnalysis::do_parallel_Profiler_on_SNAP", &tProfSNAP));
	//TEST START	
	if(TEST_FLAG)
	  {
	    TSpecificFunctor<CAnalysis> 
	      tProfSNAP(Analysis, &CAnalysis::do_parallel_Test_on_SNAP);
	    if(ANALYSIS_PROFILE)	
	      m_jobsQueue.insert(make_pair("CAnalysis::do_parallel_Test_on_SNAP", &tProfSNAP));
	//TEST END
	  }
	
	///////////////////////////////////////////////
	// RUN ALL JOBS //
	for(TJobsQueue::iterator it=m_jobsQueue.begin();
	    it!=m_jobsQueue.end();++it)
	  {
	    {
	    string jobmsg=string("\t# ")+(*it).first+string(" ");
	    cout<<"#We are doing JOB on "<<Analysis->GetNumberOfThreads()<<" threads:\t\n\t"<<jobmsg<<endl;
	    scoped_timer timethis(jobmsg.c_str());
	    Analysis->parallel_do_RUN((*it).second,SNAP_START, SNAP_END);
	    }
	    
	  }
	///////////////////////////////////////////////
	//	WriteResults
	if(!ANALYSIS_PROFILE)
			Analysis->DumpOrbitsOAF();
	///////////////////////////////////////////////
	delete Analysis;
}

